perm filename RPLACA[F80,JMC] blob sn#566513 filedate 1981-02-23 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.require "memo.pub[let,jmc]" source
C00005 00003	c(xx,mem) - The contents off the location xx when the memory state is mem.
C00007 ENDMK
C⊗;
.require "memo.pub[let,jmc]" source;
.at "qgo" ⊂"%3go_to%*"⊃
.at "qbegin" ⊂"%3begin%*"⊃
.at "end" ⊂"%endn%*"⊃
.at "end" ⊂"%endn%*"⊃
.cb Correctness of Programs that Modify List Structure

	Consider the LISP program ⊗nconc defined by

.begin nofill

nconc[u,v] ← qif qn u qthen v
		qelse prog[[w]
	w ← u
l:	qif qn qd w qthen qbegin jnk ← rplacd[w,v]; return u qend;
	w ← qd w
	qgo l]
.end

	⊗nconc is a destructive version of ⊗append in that a variable
whose value is ⊗u is changed to have value ⊗u*v.
Other variables are unchanged if they don't merge with the top
level of ⊗u.  How shall we state this formally and prove it?

	We begin by distinguishing between S-expressions and
pointers and by introducing the memory state ⊗mem and
the function ⊗val(uu,m).  We shall use single letters for variables
whose values are S-expressions and doubled letters for variables whose
values are pointers.  A typical relation might be

	%2val(xx,mem) = x%1

meaning that the pointer ⊗xx points to a list structure representing
the S-expression which is the value of the S-expression variable
⊗x.  

	We now introduce ⊗nconc(xx,_vv,_mem) as a two output function
whose value is a new pointer and a new memory state.  We shall
want to prove

	%2∀uu mem. val(nconc(uu, vv, mem) = val(uu, mem) * val(vv, mem)%1

as the relation between ⊗nconc and ⊗append. 
However, this isn't all we will need to prove about ⊗nconc. 

	The program can now be written cleanly as

.begin nofill

%2nconc[uu, vv, mem] ← qif null[uu, mem] qthen vv, mem
			qelse prog[[ww, jjnk]
	ww ← uu;
l:	qif null cdr[ww, mem] qthen 
		qbegin jjnk, mem ← rplacd[ww, vv, mem] return2[uu, mem] qend;
	ww ← cdr[ww, mem];
	qgo l]%1.
.end

	Perhaps we should now try to elephantize the program, but it
still isn't clear how to elephantize function calls.

c(xx,mem) - The contents off the location xx when the memory state is mem.

issexp(xx,mem) - True if  xx points to a list structure representing an
S-expression

sexp(xx,mem) - The S-expression represented by the pointer xx in mem.

satom(xx,mem) - True if xx points to an atom.

atomrep(xx,mem) - The atom pointed to by xx.

	We have the axiom

	∀xx mem.[satom(xx,mem) ⊃ atom atomrep(xx,mem)],

which asserts that a when a pointer satisfies the test for an atom,
the function atomrep returns an atom.

	With these we can make the recursive definition

	sexp(xx,mem) ← if satom(xx,mem) then atomrep(xx,mem)
else sexp(left c(xx,mem),mem).sexp(right c(xx,mem),mem).